/*
 * This file is part of the Boring Engine's Kirby Game.
 *
 * Copyright (c) 2011 by pf5234 <pf5234@users.sourceforge.net>.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

package kirby;

import com.googlecode.boringengine.Animator;
import com.googlecode.boringengine.Render;
import java.util.ArrayList;
import java.util.Iterator;

public abstract class Projectile extends GameObject {

    protected boolean flipped, isDead;

    public Projectile(boolean flip, int x1, int y1) {
        anim = new Animator("resources/gfx/projectile", Resources.l);
        flipped = flip;
        x = x1;
        y = y1;
    }

    /*@Override
    public void doCollide(GameObject obj) {
        if (state == State.NOTHING) return;
        if (state == State.SUCKING) {
            doSucking(obj);
            return;
        }
        if (!(obj instanceof Enemy)) return;
        ((Enemy)obj).health -= 50;
        disappear();
    }*/

    public void draw() {
        Render.addScale(2);
        anim.draw(x, y, flipped);
        Render.addScale(.5);
    }

    public boolean isEdible() {
        return false;
    }

    public String save() {
        return null;
    }

    public boolean isDead() {
        return isDead;
    }

    public void die() {
        isDead = true;
    }

    public static class Air extends Projectile {

        private double airDX;
        private int airWait;

        public Air(boolean flip, int x, int y) {
            super(flip, x, y);
            w = h = 32;
            airDX = 7;
            anim.changeAnimation("air");
        }

        @Override
        public void doCollide(GameObject obj) {
            if (!(obj instanceof Enemy)) return;
            ((Enemy)obj).health -= 50;
            die();
        }

        @Override
        public void update0() {
            if (airDX <= 0) {
                if (airWait <= 0)
                    die();
                else
                    airWait--;
                return;
            }
            airDX -= .125;
            x += flipped ? -airDX : airDX;
            if (airDX <= 0)
                airWait = 20;
        }
    }

    public static class Star extends Projectile {

        public Star(boolean flip, int x, int y) {
            super(flip, x, y);
            w = h = 32;
            anim.changeAnimation("star");
        }

        @Override
        public void doCollide(GameObject obj) {
            if (!(obj instanceof Enemy)) return;
            ((Enemy)obj).health -= 50;
            die();
        }

        @Override
        public void update0() {
            int three = flipped ? -7 : 7;
            int ret = CollisionDetection.canMoveToX(x, y, w, h, three);
            if (ret == CollisionDetection.CANT_MOVE)
                die();
            else
                x += three;
        }
    }

    public static class Sucking extends Projectile {

        private int suckingDistance = 0;
        private ArrayList<GameObject> objectsSucked = new ArrayList<GameObject>();

        public Sucking(boolean flip, int x, int y) {
            super(flip, x, y);
            w = h = 48;
        }

        @Override
        public void draw() {}

        public void update0() {
            Iterator<GameObject> iter = objectsSucked.iterator();
            while (iter.hasNext()) {
                GameObject obj = iter.next();
                obj.x += flipped ? 2 : -2;
                int distance;
                if (flipped) distance = (x+32) - obj.x;
                else distance = obj.x - (x+16);
                if (distance <= 0) {
                    iter.remove();
                    if (obj instanceof Enemy) ((Enemy)obj).beenEaten();
                }
            }
            suckingDistance -= 2;
        }

        public void doCollide(GameObject obj) {
            if (obj.isEdible()) {
                if (obj instanceof Item) return;
                if (objectsSucked.contains(obj)) return;
                if (obj instanceof Enemy) ((Enemy)obj).beingEaten();
                objectsSucked.add(obj);
                int distance;
                if (flipped) distance = (x+w) - obj.x;
                else distance = obj.x - x;
                if (distance > suckingDistance) suckingDistance = distance;
            }
        }

        @Override
        public void die() {
            for (GameObject obj : objectsSucked) {
                if (obj instanceof Enemy) ((Enemy)obj).health -= 50;
            }
            isDead = true;
        }

        boolean stillSucking() {
            return suckingDistance > 0;
        }

        void move(int x1, int y1) {
            x = x1; y = y1;
        }
    }
}
